import * as Cesium from 'cesium/Cesium'
import AxisLinePrimitive from "./AxisLinePrimitive";
import getWidgetOrigin from "./getWidgetOrigin";
import TransformAxis from "./TransformAxis";

var noScale$2 = new Cesium.Cartesian3(1,1,1)
    , offsetScratch$d = new Cesium.Cartesian3
    , widgetOriginScratch = new Cesium.Cartesian3
    , rotationWorldScratch = new Cesium.Cartesian3
    , rotatedTransformScratch = new Cesium.Matrix4
    , inverseTransformScratch = new Cesium.Matrix4
    , localStartScratch = new Cesium.Cartesian3
    , localEndScratch = new Cesium.Cartesian3
    , vector1Scratch = new Cesium.Cartesian2
    , vector2Scratch = new Cesium.Cartesian2
    , hprScratch = new Cesium.HeadingPitchRoll
    , rayScratch$5 = new Cesium.Ray
    , intersectionScratch$2 = new Cesium.Cartesian3
    , quaternionScratch$4 = new Cesium.Quaternion
    , matrix3Scratch$2 = new Cesium.Matrix3;

function getUnitCirclePositions() {
    for (var e = [], t = [], i = [], r = 0; r < 360; r++) {
        var n = Cesium.Math.toRadians(r)
            , a = Math.cos(n)
            , o = Math.sin(n);
        e.push(new Cesium.Cartesian3(0,a,o)),
            t.push(new Cesium.Cartesian3(o,0,a)),
            i.push(new Cesium.Cartesian3(a,o,0))
    }
    return {
        x: e,
        y: t,
        z: i
    }
}
function getRotationAngle(e, t, i, r, n) {
    var a = Cesium.Matrix4.inverse(e, inverseTransformScratch)
        , o = Cesium.Matrix4.multiplyByPoint(a, r, localStartScratch)
        , s = Cesium.Matrix4.multiplyByPoint(a, n, localEndScratch);
    o = Cesium.Cartesian3.subtract(o, t, o),
        s = Cesium.Cartesian3.subtract(s, t, s);
    var l = vector1Scratch
        , c = vector2Scratch;
    i.x ? (l.x = o.y,
        l.y = o.z,
        c.x = s.y,
        c.y = s.z) : i.y ? (l.x = -o.x,
        l.y = o.z,
        c.x = -s.x,
        c.y = s.z) : (l.x = o.x,
        l.y = o.y,
        c.x = s.x,
        c.y = s.y);
    var u = 0 <= l.x * c.y - l.y * c.x
        , d = Cesium.Cartesian2.angleBetween(l, c);
    return u || (d = -d),
        d
}
function getLinePrimitive(e, t) {
    return new AxisLinePrimitive({
        positions: e,
        color: TransformAxis.getColor(t),
        loop: !0,
        show: !1,
        id: t
    })
}

function RotationEditor(e) {
    var t = (e = Cesium.defaultValue(e, Cesium.defaultValue.EMPTY_OBJECT)).scene;
    this._vectorLine1 = t.primitives.add(new AxisLinePrimitive({
        width: 5,
        positions: [new Cesium.Cartesian3, new Cesium.Cartesian3],
        color: Cesium.Color.YELLOW,
        show: !1
    })),
        this._vectorLine2 = t.primitives.add(new AxisLinePrimitive({
            width: 5,
            positions: [new Cesium.Cartesian3, new Cesium.Cartesian3],
            color: Cesium.Color.YELLOW,
            show: !1
        }));
    var i = getUnitCirclePositions();
    this._polylineX = t.primitives.add(getLinePrimitive(i.x, TransformAxis.X)),
        this._polylineY = t.primitives.add(getLinePrimitive(i.y, TransformAxis.Y)),
        this._polylineZ = t.primitives.add(getLinePrimitive(i.z, TransformAxis.Z)),
        this._modelMatrix = Cesium.Matrix4.clone(Cesium.Matrix4.IDENTITY),
        this.originOffset = e.originOffset,
        this._scene = t,
        this._setHPRCallback = e.setHeadingPitchRoll,
        this._setPositionCallback = e.setPosition,
        this._transform = e.transform,
        this._radius = e.radius,
        this._active = !1,
        this._dragging = !1,
        this._startTransform = new Cesium.Matrix4,
        this._startRotation = new Cesium.Matrix3,
        this._widgetOrigin = new Cesium.Cartesian3,
        this._modelOrigin = new Cesium.Cartesian3,
        this._rotationAxis = void 0,
        this._rotationPlane = new Cesium.Plane(Cesium.Cartesian3.UNIT_X,0),
        this._rotationStartPoint = new Cesium.Cartesian3,
        this.update()
}
Cesium.defineProperties(RotationEditor.prototype, {
    active: {
        get: function() {
            return this._active
        },
        set: function(e) {
            (this._active = e) ? (this._polylineX.show = !0,
                this._polylineY.show = !0,
                this._polylineZ.show = !0) : (this._polylineX.show = !1,
                this._polylineY.show = !1,
                this._polylineZ.show = !1,
                this._dragging = !1)
        }
    }
}),
    RotationEditor.prototype.update = function() {
        var e = this._transform
            , t = this._modelMatrix;
        t = Cesium.Matrix4.setScale(e, noScale$2, t);
        var i = getWidgetOrigin(e, this.originOffset, widgetOriginScratch);
        t = Cesium.Matrix4.setTranslation(t, i, t);
        var r = this._radius * Cesium.Matrix4.getMaximumScale(this._transform) * 1.25;
        t = Cesium.Matrix4.multiplyByUniformScale(t, r, t),
            this._polylineX.modelMatrix = t,
            this._polylineY.modelMatrix = t,
            this._polylineZ.modelMatrix = t
    }
    ,
    RotationEditor.prototype.handleLeftDown = function(e) {
        for (var t, i = this._scene, r = i.drillPick(e), n = 0; n < r.length; n++) {
            var a = r[n];
            if (Cesium.defined(a.id) && Cesium.defined(TransformAxis[a.id])) {
                t = a.id;
                break
            }
        }
        if (Cesium.defined(t)) {
            var o = TransformAxis.getValue(t)
                , s = Cesium.Matrix4.setScale(this._transform, noScale$2, this._startTransform);
            this._startRotation = Cesium.Matrix4.getMatrix3(s, this._startRotation);
            var l = Cesium.Matrix4.getTranslation(s, this._modelOrigin)
                , c = getWidgetOrigin(this._transform, this.originOffset, this._widgetOrigin)
                , u = Cesium.Matrix4.multiplyByPoint(s, o, rotationWorldScratch)
                , d = Cesium.Cartesian3.subtract(u, l, u);
            d = Cesium.Cartesian3.normalize(d, d);
            var h = Cesium.Plane.fromPointNormal(c, d, this._rotationPlane)
                , p = Cesium.IntersectionTests.rayPlane(i.camera.getPickRay(e, rayScratch$5), h, this._rotationStartPoint);
            this._dragging = Cesium.defined(p),
                this._rotationAxis = o,
                i.screenSpaceCameraController.enableInputs = !1
        }
    }
    ,
    RotationEditor.prototype.handleMouseMove = function(e) {
        if (this._dragging) {
            var t = this._scene
                , i = t.camera.getPickRay(e, rayScratch$5)
                , r = Cesium.IntersectionTests.rayPlane(i, this._rotationPlane, intersectionScratch$2);
            if (Cesium.defined(r)) {
                var n = this._widgetOrigin
                    , a = this._modelOrigin
                    , o = this._rotationStartPoint
                    , s = this._vectorLine1
                    , l = s.positions
                    , c = this._vectorLine2
                    , u = c.positions
                    , d = Cesium.Cartesian3.subtract(o, n, vector1Scratch)
                    , h = Cesium.Cartesian3.subtract(r, n, vector2Scratch);
                h = Cesium.Cartesian3.normalize(h, h),
                    h = Cesium.Cartesian3.multiplyByScalar(h, Cesium.Cartesian3.magnitude(d), h),
                    r = Cesium.Cartesian3.add(n, h, r),
                    l[0] = n,
                    l[1] = o,
                    u[0] = n,
                    u[1] = r,
                    s.positions = l,
                    c.positions = u,
                    s.show = !0,
                    c.show = !0;
                var p = Cesium.Cartesian3.multiplyComponents(this.originOffset, Cesium.Matrix4.getScale(this._transform, offsetScratch$d), offsetScratch$d)
                    , m = this._rotationAxis
                    , f = getRotationAngle(this._startTransform, p, m, o, r)
                    , g = Cesium.Matrix3.fromQuaternion(Cesium.Quaternion.fromAxisAngle(m, f, quaternionScratch$4), matrix3Scratch$2);
                g = Cesium.Matrix3.multiply(this._startRotation, g, g);
                var _ = Cesium.Matrix4.fromRotationTranslation(g, a, rotatedTransformScratch);
                this._setHPRCallback(Cesium.Transforms.fixedFrameToHeadingPitchRoll(_, t.mapProjection.ellipsoid, void 0, hprScratch));
                var v = Cesium.Cartesian3.negate(p, vector1Scratch);
                v = Cesium.Matrix3.multiplyByVector(g, v, v),
                    a = Cesium.Cartesian3.add(v, n, a),
                    this._setPositionCallback(a)
            }
        }
    }
    ,
    RotationEditor.prototype.handleLeftUp = function() {
        this._dragging = !1,
            this._vectorLine1.show = !1,
            this._vectorLine2.show = !1,
            this._scene.screenSpaceCameraController.enableInputs = !0
    }
    ,
    RotationEditor.prototype.isDestroyed = function() {
        return !1
    }
    ,
    RotationEditor.prototype.destroy = function() {
        this.active = !1;
        var e = this._scene;
        e.primitives.remove(this._vectorLine1),
            e.primitives.remove(this._vectorLine2),
            e.primitives.remove(this._polylineX),
            e.primitives.remove(this._polylineY),
            e.primitives.remove(this._polylineZ),
            Cesium.destroyObject(this)
    }
    ,
    RotationEditor._getRotationAngle = getRotationAngle;

export default RotationEditor;